<?php

namespace app\shop\exception;

use app\shop\library\response\ResponseCode;
use app\shop\library\ShopAuth;
use app\shop\library\ShopLogHelper;
use Exception;
use Throwable;

class CustomException extends Exception
{
    /**
     * @var int
     * 业务状态码
     */
    protected int $businessCode = ResponseCode::FAIL['code'];

    /**
     * 错误提示信息
     * @var string
     */
    protected string $errorMsg = ResponseCode::FAIL['msg'];

    /**
     * 额外记录到日志的错误信息
     * @var array
     */
    protected array $errorInfo = [];

    /**
     * Http状态码
     * @var int
     */
    public int $httpStatus = ResponseCode::FAIL['code'];

    /**
     * 强制写入日志
     * @var bool
     */
    public bool $forceLog = false;

    public function __construct(string $message = "", Throwable $previous = null, int $code = ResponseCode::FAIL['code'])
    {
        if ($previous) {
            $this->errorInfo = array_merge($this->errorInfo, [
                'exception' => [
                    'message' => $previous->getMessage(),
                    'file'    => $previous->getFile(),
                    'line'    => $previous->getLine(),
                ],
            ]);
        }
        if ($this->forceLog) {
            $this->addErrorLog();
        }

        parent::__construct($message, $code, $previous);
    }

    public function getError(): array
    {
        return [
            'code' => $this->businessCode,
            'msg'  => $this->errorMsg,
            'data' => $this->errorInfo
        ];
    }

    /**
     * 记录到日志
     */
    public function addErrorLog(): void
    {
        $request = request();

        $request_data = [
            'url'    => $request->url(),
            'method' => $request->method(),
            'params' => $request->param(),
        ];
        //追加用户ID
        if ($request->header('token')) {
            $request_data['user'] = ShopAuth::instance()->getUserInfo();
        }
        // 记录异常日志
        $context = [
            '请求时间' => date('Y-m-d H:i:s'),
            '请求信息' => $request_data,
            '错误信息' => $this->errorInfo
        ];

        ShopLogHelper::error('异常信息记录', $context);
    }
}

